#    Copyright 2011 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPIP.
#    COOPIP is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPIP is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPIP.  If not, see <http://www.gnu.org/licenses/>.

#************************BEGIN Add Include Files to Path************************
import sys
IncludePath="/var/coopip/djangoproject/include"
if(not IncludePath in sys.path):
    sys.path.append(IncludePath)


    
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime

#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopip/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)
from django.core.management import setup_environ
import djangoproject.settings
setup_environ(djangoproject.settings)
from djangoproject.models import *
from django.contrib.gis.geos import GEOSGeometry
import CIS, AMR, OMS, GIS
import COOPIP_Misc
#********************Setup psycopg2 and django section********************


import urllib
import httplib
import datetime
import time


def PingNearbyMeterIfConditionsMet(meter):
    if(not COOPIP_Misc.MakeSureNotTooManyPendingMeterPings(meter.Substation)):
        return
    Now = datetime.datetime.now()
    SecondsSinceLastPingAttempt = (Now - meter.LastPingOutDateTime).total_seconds()
    if(SecondsSinceLastPingAttempt > 900):  
        print "Pinging:  " + str(meter)
        meter.SendPingToAMRIndicator=True
        meter.save()


def CheckFailedMetersforTCReads():
    #check failed meters for tc reads; if present, import as meterping objects
    FailedMeters = Meter.objects.filter(Symbology='failed')
    for meter in FailedMeters:
       #metertcreadtype 2 are manually-fired, type 1 are daily shift reads
       if meter.LastAMRTCReadDateTime:
           ManualTCReads = AMR.Meteracctstc.objects.filter(serialnumber=meter.SerialNumber, metertcreadtype=2).filter(metertccurdatetime__gt=meter.LastAMRTCReadDateTime)
       else:
           Yesterday = datetime.datetime.now() - datetime.timedelta(hours=24)
           ManualTCReads = AMR.Meteracctstc.objects.filter(serialnumber=meter.SerialNumber, metertcreadtype=2).filter(metertccurdatetime__gt=Yesterday)
       if not ManualTCReads.count():
           #print 'No reads'
           continue
       LatestRead = ManualTCReads.order_by('-metertccurdatetime')[0]
       meter.LastAMRTCReadDateTime = LatestRead.metertccurdatetime
       if LatestRead.metertcqualitycode == 3 or LatestRead.metertcqualitycode == 6:
           SuccessIndicator=True
       else:
           SuccessIndicator=False
       meter.LastPingSuccessIndicator=SuccessIndicator
       meter.LastPingResponseDateTime = LatestRead.metertccurdatetime
       meter.save()
       meter.CalculateSymbology()
       meter.CalculateIncidentSymbology()
       print 'Used Reading for ' + str(meter.SerialNumber)
       

        


Start = datetime.datetime.now()
SecondsElapsed = (Start - datetime.datetime.now()).total_seconds()
while(SecondsElapsed < 60):
    MeterPing().GetLatestFromAMR()
    MeterPing().CleanupAMRPingResponses()
    NewMeterPingFailureList = MeterPing.UpdateMetersWithLatestResults()
    MeterPing.GetLatestCOOPTalkSuccessReads()
    CheckFailedMetersforTCReads()
    MaxMetersToPing =  10
    MeterPingCount = 0
    for meter in NewMeterPingFailureList:
        #Meters sometimes will fail but succeed after performing a TC Read on them, so perform a TC Read on all new failures.
        if(not meter.LastTCReadAttemptDateTime):
            COOPTalk.OutInitiateMeterReadByMeterNumber(meter.SerialNumber)
            meter.LastTCReadAttemptDateTime = datetime.datetime.now()
            meter.save()
        else:  
            TimeSinceLastTCRead = (datetime.datetime.now() - (meter.LastTCReadAttemptDateTime)).total_seconds()
            if(TimeSinceLastTCRead > (10 * 60 * 15)):  #Do not attempt additional TC Reads very ofte (10 hour delay)
                COOPTalk.OutInitiateMeterReadByMeterNumber(meter.SerialNumber)
                meter.LastTCReadAttemptDateTime = datetime.datetime.now()
                meter.save()
        NearbyMeters=Meter.objects.filter(Point__distance_lte=(meter.Point, 5280)).filter(AMRCircuitName=meter.AMRCircuitName).filter(Symbology='success').order_by('LastPingOutDateTime')
        for nearbyMeter in NearbyMeters:
            PingNearbyMeterIfConditionsMet(nearbyMeter)
            MeterPingCount = MeterPingCount + 1
            if(MeterPingCount > MaxMetersToPing):
                break
    COOPTalk.SendAllOut()
    time.sleep(15)
    SecondsElapsed = (datetime.datetime.now() - Start).total_seconds()
    print SecondsElapsed

        

